package com.school.zhaoban.config;

import com.school.zhaoban.response.CommonResponse;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;

/**
 * @author 又菜又爱玩
 * @version 1.0
 * @date 2022/2/19 13:37
 * @blog https://blog.csdn.net/biancheng4/article/details/121727982
 */

@Slf4j
@RestControllerAdvice
public class ExceptionControllerAdvice {


    /**
     * 业务异常处理
     *
     * @param e 业务异常
     * @return
     */
    @ExceptionHandler(value = BusinessException.class)
    public CommonResponse exceptionHandler(BusinessException e) {
        log.error("业务异常:{}", e.getErrorMsg());
        return CommonResponse.fail(e.getCode(), e.getErrorMsg());
    }


    @ExceptionHandler(MethodArgumentNotValidException.class)
    public CommonResponse MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
        log.info("校验时异常:{}", e.getMessage(), e);
        // 注意哦，这里返回类型是自定义响应体
        return CommonResponse.fail();
    }

    /** 运行时异常 */
    @ExceptionHandler(RuntimeException.class)
    public CommonResponse runtimeExceptionHandler(RuntimeException ex) {
        log.error("运行时异常：{}", ex.getMessage(), ex);
        return CommonResponse.fail(201,"运行时异常");
    }

    /** 空指针异常 */
    @ExceptionHandler(NullPointerException.class)
    public CommonResponse nullPointerExceptionHandler(NullPointerException ex) {
        log.error("空指针异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"空指针异常");
    }

    /** 类型转换异常 */
    @ExceptionHandler(ClassCastException.class)
    public CommonResponse classCastExceptionHandler(ClassCastException ex) {
        log.error("类型转换异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"类型转换异常");
    }
    /** 文件未找到异常 */
    @ExceptionHandler(FileNotFoundException.class)
    public CommonResponse FileNotFoundException(FileNotFoundException ex) {
        log.error("文件未找到异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"文件未找到异常");
    }
    /** 数字格式异常 */
    @ExceptionHandler(NumberFormatException.class)
    public CommonResponse NumberFormatException(NumberFormatException ex) {
        log.error("数字格式异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"数字格式异常");
    }
    /** 安全异常 */
    @ExceptionHandler(SecurityException.class)
    public CommonResponse SecurityException(SecurityException ex) {
        log.error("安全异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"安全异常");
    }
    /** sql异常 */
    @ExceptionHandler(SQLException.class)
    public CommonResponse SQLException(SQLException ex) {
        log.error("sql异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"sql异常");
    }
    /** 类型不存在异常 */
    @ExceptionHandler(TypeNotPresentException.class)
    public CommonResponse TypeNotPresentException(TypeNotPresentException ex) {
        log.error("类型不存在异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"类型不存在异常");
    }

    /** IO异常 */
    @ExceptionHandler(IOException.class)
    public CommonResponse iOExceptionHandler(IOException ex) {
        log.error("IO异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"IO异常");
    }

    /** 未知方法异常 */
    @ExceptionHandler(NoSuchMethodException.class)
    public CommonResponse noSuchMethodExceptionHandler(NoSuchMethodException ex) {
        log.error("未知方法异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"未知方法异常");
    }

    /** 数组越界异常 */
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public CommonResponse indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
        log.error("数组越界异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"数组越界异常");
    }
    /** sql语法错误异常 */
    @ExceptionHandler(BadSqlGrammarException.class)
    public CommonResponse BadSqlGrammarException(BadSqlGrammarException ex) {
        log.error("sql语法错误异常：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"sql语法错误异常");
    }

    /** 无法注入bean异常 */
    @ExceptionHandler(NoSuchBeanDefinitionException.class)
    public CommonResponse NoSuchBeanDefinitionException(NoSuchBeanDefinitionException ex) {
        log.error("无法注入bean异常 ：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"无法注入bean");
    }

    /** Http消息不可读异常 */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public CommonResponse requestNotReadable(HttpMessageNotReadableException ex) {
        log.error("400错误..requestNotReadable：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"Http消息不可读");
    }

    /** 400错误 */
    @ExceptionHandler({TypeMismatchException.class})
    public CommonResponse requestTypeMismatch(TypeMismatchException ex) {
        log.error("400错误..TypeMismatchException：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(210,"服务器异常");
    }

    /** 500错误 */
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    public CommonResponse server500(RuntimeException ex) {
        log.error("500错误：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(201,"服务器异常");
    }

    /** 栈溢出 */
    @ExceptionHandler({StackOverflowError.class})
    public CommonResponse requestStackOverflow(StackOverflowError ex) {
        log.error("栈溢出：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(210,"栈溢出异常");
    }

    /** 除数不能为0 */
    @ExceptionHandler({ArithmeticException.class})
    public CommonResponse arithmeticException(ArithmeticException ex) {
        log.error("除数不能为0：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(210,"除数不能为0异常");
    }

    /** 其他错误 */
    @ExceptionHandler({Exception.class})
    public CommonResponse exception(Exception ex) {
        log.error("其他错误：{} ", ex.getMessage(), ex);
        return CommonResponse.fail(210,"网络连接失败，请退出后再试");
    }
}
